package trab3;

import java.util.*;

import sim.core.*;
import sim.util.*;

class NodeDB {
	static RandomList<Node> nodes = new RandomList<Node>();
	static TreeMap<Integer, Node> k2n = new TreeMap<Integer, Node>();

	synchronized static int store(Node n) {
		nodes.add(n) ;
		int index = k2n.size() ;
		k2n.put( index, n ) ;
		return index ;
	}

	synchronized Set<Integer> keys() {
		return k2n.keySet();
	}

	synchronized static void dispose(Node n) {
		if (n != null) {
			k2n.remove(n.index);
			seeds.remove(n);
			nodes.remove(n);
			n.dispose();
		}
	}

	static int size() {
		return k2n.size();
	}

	synchronized static RandomList<EndPoint> endpoints() {
		RandomList<EndPoint> res = new RandomList<EndPoint>();
		for (Node i : nodes)
			res.add(i.endpoint);
		return res;
	}

	static Node randomNode() {
		return nodes.randomElement();
	}

	static RandomList<Node> seeds = new RandomList<Node>();

	static RandomList<EndPoint> randomEndPoints(Node caller, int total) {

		while (seeds.size() < total) {
			Node x = NodeDB.randomNode();
			if (!seeds.contains(x))
				seeds.add(x);
		}

		Set<EndPoint> res = new HashSet<EndPoint>();
		while (res.size() < total) {
			Node x = seeds.randomElement();
			if (x != caller)
				res.add(x.endpoint);
		}

		if (!seeds.contains(caller))
			seeds.add(caller);

		return new RandomList<EndPoint>(res);
	}

	static RandomList<EndPoint> closestNodes(Node center, int total) {
		TreeSet<EndPoint> sl = new TreeSet<EndPoint>(new EDP(center.endpoint));
		for (Node i : nodes)
			sl.add(i.endpoint);

		RandomList<EndPoint> res = new RandomList<EndPoint>();
		for (EndPoint i : sl) {
			res.add(i);
			if (total-- == 0)
				break;
		}
		return res;
	}
}

class EDP implements Comparator<EndPoint> {

	EndPoint center;

	public EDP(EndPoint _center) {
		center = _center;
	}

	public int compare(EndPoint a, EndPoint b) {
		double da = center.distance(a);
		double db = center.distance(b);
		if (da == db) {
			return a.hashCode() < b.hashCode() ? -1 : 1;
		}
		return da < db ? -1 : 1;
	}
}